package com.example.redissontest.controller;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName RedissonController
 * @Description
 * @Author huyingliang
 * @Date 2024/1/4 15:45
 */
@RequestMapping("/my")
@RestController
public class RedissonController {

    @Autowired
    private RedissonClient redissonTemplate;

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

    @GetMapping("/add")
    public String add() {
        redissonTemplate.getBucket("name").set("hyl");
        return "success";
    }

    @GetMapping("/get")
    public String get() {
        return redissonTemplate.getBucket("name").get().toString();
    }

    @GetMapping("/getAndIncrement")
    public String getAndIncrement() {
        /*先获取 然后再增加  例如当前是10 那么返回值就是10，但是库中已经是11*/
        long getAndIncrement = redissonTemplate.getAtomicLong("age").getAndIncrement();
        return String.valueOf(getAndIncrement);
    }

    @GetMapping("/incrementAndGet")
    public String incrementAndGet() {
        /*先获取再增加 例如当前是14 那么返回值就是15 库中也是15*/
        long incrementAndGet = redissonTemplate.getAtomicLong("age").incrementAndGet();
        return String.valueOf(incrementAndGet);
    }

    @GetMapping("/lock")
    public String lock() {
        RLock lock = redissonTemplate.getLock("lock");
//        lock() 方法是阻塞获取锁的方式，如果当前锁被其他线程持有，则当前线程会一直阻塞等待获取锁，
//        1.直到获取到锁  2.或者发生超时或中断等情况才会结束等待。
//        该方法获取到锁之后可以保证线程对共享资源的访问是互斥的，适用于需要确保共享资源只能被一个线程访问的场景。
//        Redisson 的 lock() 方法支持可重入锁和公平锁等特性，可以更好地满足多线程并发访问的需求。
        lock.lock();
        try {
            System.out.println("lock");
        } finally {
            lock.unlock();
        }

//        而 tryLock() 方法是一种非阻塞获取锁的方式，在尝试获取锁时不会阻塞当前线程，而是
//        立即
//        返回获取锁的结果，如果获取成功则返回 true，否则返回 false。Redisson 的 tryLock() 方法支持加锁时间限制、
//        等待时间限制以及可重入等特性，可以更好地控制获取锁的过程和等待时间，避免程序出现长时间无法响应等问题。
        if (lock.tryLock()) {
            try {
                System.out.println("tryLock");
            } finally {
                lock.unlock();
            }
        }
        return "success";
    }

}
